package de.koller.reason.render.ray;

import de.koller.oceanFramework.math.RVec3;
import de.koller.oceanFramework.util.ColorIntUtil;
import de.koller.reason.render.obj.Polygon;
import java.util.List;

public class FragmentRay {

	private final RayRenderer renderer;
	private final Ray[] ray;
	private final Ray midRay;
	
	public FragmentRay( RayRenderer renderer, int x, int y ) {
		this.renderer = renderer;
		
		float h = (float)renderer.raster.height / (float)renderer.raster.width;
		float sx = (float)x / (float)renderer.raster.width - .5f;
		float sy = (float)y / (float)renderer.raster.width - (h/2f);
		float sxp = (float)(x+1) / (float)renderer.raster.width - .5f;
		float syp = (float)(y+1) / (float)renderer.raster.width - (h/2f);
		float sxm = (x+.5f) / (float)renderer.raster.width - .5f;
		float sym = (y+.5f) / (float)renderer.raster.width - (h/2f);
		
		ray = new Ray[4];
		ray[0] = Ray.create( RayRenderer.FOV, h, sx, sy, RayRenderer.FARPLANE );
		ray[1] = Ray.create( RayRenderer.FOV, h, sx, syp, RayRenderer.FARPLANE );
		ray[2] = Ray.create( RayRenderer.FOV, h, sxp, syp, RayRenderer.FARPLANE );
		ray[3] = Ray.create( RayRenderer.FOV, h, sxp, sy, RayRenderer.FARPLANE );
		
		midRay = Ray.create( RayRenderer.FOV, h, sxm, sym, RayRenderer.FARPLANE );
	}
	
	public int getRasterColor() {
		List<Intersectioner.RayIntersection> intersections = Intersectioner.cast( midRay, renderer.data.getPolygons() );
		
		if( !intersections.isEmpty() )
			return fragment( intersections );
		
		return 0xff000000;
	}
	
	private int fragment( List<Intersectioner.RayIntersection> intersections ) {
		Intersectioner.RayIntersection i = intersections.get( 0 );
		return fragmentTexture( i.polygon, i.intersectionPoint );
	}
	
	private int fragmentTexture( Polygon p, RVec3 at ) {
		if( p.texture == null )
			return fragmentColor( p, at );
		
		
		
		RVec3[] uv = new RVec3[4];
		Interpolator i = new Interpolator();
		for( int j = 0; j < 4; j++ ) {
			RVec3 atr = Intersectioner.getRayTrace( ray[j].a, ray[j].b, 
					p.verteces[0].position, p.verteces[1].position, p.verteces[2].position, true, true );
			float u = i.interpolate( p, atr, p.verteces[0].uvw.x, p.verteces[1].uvw.x, p.verteces[2].uvw.x );
			float v = i.interpolate( p, atr, p.verteces[0].uvw.y, p.verteces[1].uvw.y, p.verteces[2].uvw.y );
			uv[j] = new RVec3( u, v, 0 );
		}
		
		return p.texture.full( uv[0], uv[1], uv[2], uv[3] );
	}
	
	private int fragmentColor( Polygon p, RVec3 at ) {
		Interpolator i = new Interpolator();
		int a = (int)i.interpolate( p, at,	ColorIntUtil.getAValue( p.verteces[0].color ),
											ColorIntUtil.getAValue( p.verteces[1].color ),
											ColorIntUtil.getAValue( p.verteces[2].color ) );
		int r = (int)i.interpolate( p, at,	ColorIntUtil.getRValue( p.verteces[0].color ),
											ColorIntUtil.getRValue( p.verteces[1].color ),
											ColorIntUtil.getRValue( p.verteces[2].color ) );
		int g = (int)i.interpolate( p, at,	ColorIntUtil.getGValue( p.verteces[0].color ),
											ColorIntUtil.getGValue( p.verteces[1].color ),
											ColorIntUtil.getGValue( p.verteces[2].color ) );
		int b = (int)i.interpolate( p, at,	ColorIntUtil.getBValue( p.verteces[0].color ),
											ColorIntUtil.getBValue( p.verteces[1].color ),
											ColorIntUtil.getBValue( p.verteces[2].color ) );
		return ColorIntUtil.getIntColor( a, r, g, b );
	}
	
}
